package com.quxiang.pay.util;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class EncryptUtil {

	private final static Logger logger = LoggerFactory.getLogger(EncryptUtil.class);

	@SuppressWarnings("rawtypes")
	public static String createSign(String characterEncoding, SortedMap<String, String> parameters, String key) {
		StringBuffer sb = new StringBuffer();
		Set es = parameters.entrySet();
		Iterator it = es.iterator();
		while (it.hasNext()) {
			Map.Entry entry = (Map.Entry) it.next();
			String k = (String) entry.getKey();
			Object v = entry.getValue();
			if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {

				sb.append(k + "=" + v + "&");
			}
		}
		sb.append("key=" + key);// 最后加密时添加商户密钥，由于key值放在最后，所以不用添加到SortMap里面去，单独处理，编码方式采用UTF-8
		logger.info("字符串见面前：{}",sb.toString());
		String sign = getMD5(sb.toString(), characterEncoding).toUpperCase();
		logger.info("字符串见面后：{}",sign);
		return sign;
	}

	/**
	 * 获取String的MD5值
	 *
	 * @param info
	 *              字符串
	 * @return 该字符串的MD5值
	 */
	private static String getMD5(String info, String characterEncoding) {
		try {
			// 获取 MessageDigest 对象，参数为 MD5 字符串，表示这是一个 MD5 算法（其他还有 SHA1
			// 算法等）：
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			// update(byte[])方法，输入原数据
			// 类似StringBuilder对象的append()方法，追加模式，属于一个累计更改的过程
			md5.update(info.getBytes(characterEncoding));
			// digest()被调用后,MessageDigest对象就被重置，即不能连续再次调用该方法计算原数据的MD5值。可以手动调用reset()方法重置输入源。
			// digest()返回值16位长度的哈希值，由byte[]承接
			byte[] md5Array = md5.digest();
			// byte[]通常我们会转化为十六进制的32位长度的字符串来使用,本文会介绍三种常用的转换方法
			return bytesToHex1(md5Array).toUpperCase();
		} catch (NoSuchAlgorithmException e) {
			return "";
		} catch (UnsupportedEncodingException e) {
			return "";
		}
	}

	private static String bytesToHex1(byte[] md5Array) {
		StringBuilder strBuilder = new StringBuilder();
		for (int i = 0; i < md5Array.length; i++) {
			int temp = 0xff & md5Array[i];// TODO:此处为什么添加 0xff & ？
			String hexString = Integer.toHexString(temp);
			if (hexString.length() == 1) {// 如果是十六进制的0f，默认只显示f，此时要补上0
				strBuilder.append("0").append(hexString);
			} else {
				strBuilder.append(hexString);
			}
		}
		return strBuilder.toString();
	}

	
	public static void main(String[] args) {
		String s = "body=测试支付&mch_create_ip=127.0.0.1&mch_id=101520000465&nonce_str=1409196838&notify_url=http://227.0.0.1:9001/javak/&out_trade_no=141903606228&service=pay.alipay.native&total_fee=1&key=58bb7db599afc86ea7f7b262c32ff42f";
	
		System.out.println(getMD5(s, "utf-8"));
	}
}
